#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <ctime>
#include <climits>
using namespace std;

const int maxn = 1005;
const double EPS = 1e-10;

inline int Max(int &a, const int &b) { if (a < b) a = b; return a; }
inline int Min(int &a, const int &b) { if (a > b) a = b; return a; }

struct node
{
  int num;
  int pre_times, post_times;
};
int width, height;
int n, m;
node pairs[maxn];
node column[3][maxn];
int column_num[3];
int pointer[3]; // the pointer to the three line.
int now, up, down; // three line;
node ans_a, ans_b;

void Solve(void);
void Fill_Calculate_line(int& now);
void Fill_line(int now);
void Calculate_line(int now);
int Calculate_w(int now, int& w, int& min_flag, int *pointer, node temp_column[][maxn]);
void Print(void);
void Debug(void)
{
  int i, j;
  for (i = 0; i < 3; i++)
    {
      printf("column_num[%d]: %d   ", i, column_num[i]);
      for (j = 0; j < column_num[i]; j++)
        {
	  printf("%d*%d ", column[i][j].num, column[i][j].post_times);
        }
      printf("\n");
    }
}

int main(void)
{
  int sum;
  while (1)
    {
      scanf("%d", &width); n = 0; sum = 0;
      if (width == 0) break;
      while (1)
        {
	  scanf("%d %d", &pairs[n].num, &pairs[n].post_times);
	  if (pairs[n].num == 0 && pairs[n].post_times == 0) break;
	  sum += pairs[n].post_times;
	  n++;
        }
      // cout << n << " " << width << " " << endl;
      if (sum % width == 0) height = sum / width;
      else height = sum / width + 1;
      memset(column, 0, sizeof(column));
      memset(column_num, 0, sizeof(column_num));
      ans_a.num = -1; m = 0;
      printf("%d\n", width);
      Solve();
      /* for (i = 0; i < n; i++)
	 {
	 printf("%d %d\n", pairs[i].num, pairs[i].post_times);
	 } */
    }
  printf("0\n");
  return 0;
}

void Solve(void)
{
  int i;
  // Fill the first three line.
  column_num[0] = 0;
  Fill_line(1);
  // cout << m << " " << pairs[m].num << " " << pairs[m].post_times << endl;
  now = 1;
  while (height)
    {
      up = (now - 1 + 3) % 3; down = (now + 1) % 3;
      // Calculate the now th line.
      if (pairs[m].post_times / 3 >= width)
	{
	  for (i = 0; i <= 1; i++)
	    {
              Fill_Calculate_line(now);
	      if (height == 0) break;
	    }
          ans_b.num = 0; ans_b.post_times = (pairs[m].post_times / width - 1) * width; height -= pairs[m].post_times / width - 1;
          pairs[m].post_times -= (pairs[m].post_times / width - 1) * width;
	  Print();
	}
      else
	{
	  // fill the next line.
	  Fill_Calculate_line(now);
	}
    }
  printf("%d %d\n", ans_a.num, ans_a.post_times);
  printf("0 0\n");
}

void Fill_Calculate_line(int& now)
{
  now = (now + 1) % 3;
  Fill_line(now);
  // Debug();
  now = (now - 1 + 3) % 3;
  height--;
  Calculate_line(now);
  now = (now + 1) % 3;
}

void Fill_line(int now)
{
  int i;
  int w;
  for (i = 0; i < column_num[now]; i++)
    {
      column[now][i].post_times = column[now][i].pre_times = 0;
    }
  column_num[now] = 0; w = 0;
  if (m == n) return ;
  while (1)
    {
      column[now][column_num[now]].num = pairs[m].num;
      column[now][column_num[now]].post_times = pairs[m].post_times;
      pairs[m].post_times = 0;
      column_num[now]++;
      w += column[now][column_num[now] - 1].post_times;
      // cout << now << " " << w << endl;
      if (w < width)
        {
	  m++;
	  if (m == n) break;
        }
      else if (w >= width)
        {
	  pairs[m].post_times += w - width;
	  if (pairs[m].post_times == 0) m++;
	  column[now][column_num[now] - 1].post_times -= w - width;
	  break;
        }
    }
}

void Calculate_line(int now)
{
  int i, j;
  int w;
  int temp;
  int min_flag; // judge if the maxest value comes from the left or right.
  node temp_column[3][maxn];
  for (i = 0; i < 3; i++)
    {
      for (j = 0; j < column_num[i]; j++)
        {
	  temp_column[i][j] = column[i][j];
        }
    }
  w = 0; pointer[0] = pointer[1] = pointer[2] = 0;
  while (w <= width && pointer[now] < column_num[now])
    {
      // Calculate the maxest absolute value of w.
      ans_b.num = Calculate_w(now, w, min_flag, pointer, temp_column); ans_b.post_times = 0;
      if (min_flag == -1)
        { // the maxest value comes from the left.
	  w++;
	  for (i = 0; i < 3; i++)
            {
	      temp_column[i][pointer[i]].post_times--;
	      temp_column[i][pointer[i]].pre_times++;
	      if (temp_column[i][pointer[i]].post_times == 0) pointer[i]++;
            }
	  ans_b.post_times = 1;
	  Print();
	  continue;
        }
      temp = INT_MAX;
      for (i = 0; i < 3; i++)
        {
	  if (temp_column[i][pointer[i]].post_times > 0 && temp_column[i][pointer[i]].post_times < temp)
	    {
	      temp = temp_column[i][pointer[i]].post_times;
	    }
        }
      temp--;
      if (temp == 0) temp = 1;
      w += temp;
      for (i = 0; i < 3; i++)
        {
	  if (temp_column[i][pointer[i]].post_times > 0)
            {
	      temp_column[i][pointer[i]].post_times -= temp;
	      temp_column[i][pointer[i]].pre_times += temp;
	      if (temp_column[i][pointer[i]].post_times == 0) pointer[i]++;
            }
        }
      ans_b.post_times += temp;
      Print();
    }
}

int Calculate_w(int now, int& w, int& min_flag, int *pointer, node temp_column[][maxn])
{
  int i, j;
  int temp;
  int maxest(0);
  min_flag = 1;
  for (i = up, j = 0; j < 3; i = (i + 1) % 3, j++)
    {
      if (i != now && pointer[i] < column_num[i])
        {
	  temp = abs(temp_column[now][pointer[now]].num - temp_column[i][pointer[i]].num);
	  if (temp > maxest)
            {
	      maxest = temp;
	      min_flag = 1;
            }
        }
      if (w + 1 < width && pointer[i] + 1 < column_num[i] && temp_column[i][pointer[i]].post_times <= 1)
        {
	  temp = abs(temp_column[now][pointer[now]].num - temp_column[i][pointer[i] + 1].num);
	  if (temp > maxest)
            {
	      maxest = temp;
	      min_flag = 1;
            }
        }
      if (w - 1 >= 0 && pointer[i] < column_num[i] && pointer[i] - 1 >= 0 && temp_column[i][pointer[i]].pre_times < 1)
        {
	  temp = abs(temp_column[now][pointer[now]].num - temp_column[i][pointer[i] - 1].num);
	  if (temp > maxest)
            {
	      maxest = temp;
	      min_flag = -1; // from the left.
            }
        }
    }
  return maxest;
}

void Print(void)
{
  if (ans_a.num != ans_b.num)
    {
      if (ans_a.num != -1)
        {
	  printf("%d %d\n", ans_a.num, ans_a.post_times);
        }
      ans_a = ans_b;
    }
  else
    {
      ans_a.post_times += ans_b.post_times;
    }
}
